package models

import (
	"github.com/astaxie/beego/logs"
	"github.com/astaxie/beego/orm"
)

func GetYamlTable(gt *[]GitPackageTable) (int64, error) {
	o := orm.NewOrm()
	num, errx := o.Raw("select *" +
		" from cve_git_package_table").QueryRows(gt)
	if errx != nil {
		logs.Error("GetYamlTable, Get data does not exist, err: ", errx)
	}
	return num, errx
}

func GetCpePackName(pc *PackageCpe, packName string) (error) {
	o := orm.NewOrm()
	errx := o.Raw("select id, cpe_packname"+
		" from cve_package_cpe where packname = ?", packName).QueryRow(pc)
	return errx
}

func CreateYamlTable(gt *GitPackageTable) (TableId int64, err error) {
	o := orm.NewOrm()
	var localgt GitPackageTable
	if gt.TableName == "openEuler_LTS_20.03" {
		gt.Brands = "openEuler-20.03-LTS"
	} else {
		gt.Brands = "master"
	}
	errx := o.Raw("select *"+
		" from cve_git_package_table where table_name = ? ", gt.TableName).QueryRow(&localgt)
	if errx != nil {
		var TableId int64
		if TableId, err = o.Insert(gt); err == nil {
			logs.Info("CreateYamlTable, insert cve_git_package_table success, "+
				"TableId: ", TableId, ", tableName: ", gt.TableName)
		} else {
			logs.Error("CreateYamlTable, insert cve_git_package_table failed,"+
				" tableName:", gt.TableName, ", err: ", err)
			return 0, err
		}
		return TableId, nil
	} else {
		gt.TableId = localgt.TableId
		gt.Brands = localgt.Brands
		if num, err := o.Update(gt); err == nil {
			logs.Info("CreateYamlTable, update cve_git_package_table success, "+
				"num: ", num, ", TableName: ", gt.TableName)
		} else {
			logs.Error("CreateYamlTable, update cve_git_package_table failed, "+
				"TableName:", gt.TableName, ", err: ", err)
			return 0, err
		}
		return gt.TableId, nil
	}
}

func GetSingleYaml(ge *GitOpenEuler) (bool, error) {
	o := orm.NewOrm()
	if ge.Version != "" && ge.Release != "" {
		localge := GitOpenEuler{PackageName: ge.PackageName, Version: ge.Version, Status: 1}
		err := o.Read(&localge, "PackageName", "Version", "Release")
		logs.Info("GetSingleYaml1, Query yaml data results: ", ge,
			", localge: ", localge, ", err: ", err)
		if err == orm.ErrNoRows {
			return false, err
		} else if err == orm.ErrMissPK {
			return false, err
		} else {
			return true, err
		}
	} else {
		localge := GitOpenEuler{PackageName: ge.PackageName, Status: 1}
		err := o.Read(&localge, "PackageName")
		logs.Info("GetSingleYaml2, Query yaml data results: ", ge,
			", localge: ", localge, ", err: ", err)
		if err == orm.ErrNoRows {
			return false, err
		} else if err == orm.ErrMissPK {
			return false, err
		} else {
			return true, err
		}
	}
}

func InsertOpenEulerRelate(getr *GitOpenEulerTableRelate) (id int64, typex string, err error) {
	o := orm.NewOrm()
	var localge GitOpenEulerTableRelate
	errx := o.Raw("select *"+
		" from cve_git_open_euler_table_relate where git_id = ? and table_name = ?",
		getr.GitId, getr.TableName).QueryRow(&localge)
	if errx != nil {
		var relateId int64
		if relateId, err = o.Insert(getr); err == nil {
			logs.Info("InsertOpenEulerRelate, insert cve_git_open_euler_table_relate success, "+
				"RelateId: ", relateId, "tableName: ", getr.TableName)
		} else {
			logs.Error("InsertOpenEulerRelate, insert cve_git_open_euler_table_relate failed, "+
				"tableName: ", getr.TableName, ", err: ", err)
			return 0, "insert", err
		}
		return relateId, "insert", nil
	} else {
		getr.RelateId = localge.RelateId
		if _, err := o.Update(getr); err == nil {
			logs.Info("InsertOpenEulerRelate, update cve_git_open_euler_table_relate success, "+
				"RelateId: ", getr.RelateId, "tableName: ", getr.TableName)
		} else {
			logs.Error("InsertOpenEulerRelate, update cve_git_open_euler_table_relate failed, "+
				"tableName: ", getr.TableName, ", err: ", err)
			return getr.RelateId, "update", err
		}
		return getr.RelateId, "update", nil
	}
}

func CreateYaml(ge *GitOpenEuler, tableValue GitPackageTable) (id int64, typex string, err error) {
	o := orm.NewOrm()
	var localge GitOpenEuler
	var getr GitOpenEulerTableRelate
	getr.TableName = tableValue.TableName
	getr.Brands = tableValue.Brands
	errx := o.Raw("select *"+
		" from cve_git_open_euler where package_name = ? and version = ?",
		ge.PackageName, ge.Version).QueryRow(&localge)
	if errx != nil {
		logs.Info("createYaml: ", localge, ",errx: ", errx)
		ge.Status = 1
		var GitId int64
		if GitId, err = o.Insert(ge); err == nil {
			logs.Info("CreateYaml, insert cve_git_open_euler success, GitId: ",
				GitId, ", packName: ", ge.PackageName)
		} else {
			logs.Error("CreateYaml, insert cve_git_open_euler failed, "+
				"packName: ", ge.PackageName, ", err: ", err)
			return 0, "insert", err
		}
		getr.GitId = GitId
		InsertOpenEulerRelate(&getr)
		return GitId, "insert", nil
	} else {
		logs.Info("createYaml: ", localge, "GitOpenEuler: ", ge)
		ge.Status = 1
		ge.GitId = localge.GitId
		if _, err := o.Update(ge); err == nil {
			logs.Info("CreateYaml, update cve_git_open_euler success, "+
				"GitId: ", ge.GitId, ", packName: ", ge.PackageName)
		} else {
			logs.Error("CreateYaml, update cve_git_open_euler failed, "+
				"packName: ", ge.PackageName, ", err: ", err)
			return ge.GitId, "update", err
		}
		getr.GitId = ge.GitId
		InsertOpenEulerRelate(&getr)
		return ge.GitId, "update", nil
	}
}

func CreateYamlDetail(gp *GitPackageInfo, ge GitOpenEuler) (id int64, typex string, err error) {
	o := orm.NewOrm()
	var localgp GitPackageInfo
	errx := o.Raw("select *"+
		" from cve_git_package_info where git_id = ? and package_name = ? and version = ?",
		ge.GitId, gp.PackageName, gp.Version).QueryRow(&localgp)
	if errx != nil {
		gp.Status = 0
		var DetailId int64
		if DetailId, err = o.Insert(gp); err == nil {
			logs.Info("CreateYamlDetail, insert cve_git_package_info success, "+
				"DetailId: ", DetailId, ",PackageName: ", gp.PackageName)
		} else {
			logs.Error("CreateYamlDetail, insert cve_git_package_info failed, "+
				"PackageName: ", gp.PackageName, ",err: ", err)
			return 0, "insert", err
		}
		return DetailId, "insert", nil
	} else {
		gp.DetailId = localgp.DetailId
		if _, err := o.Update(gp); err == nil {
			logs.Info("CreateYamlDetail, update cve_git_package_info success, "+
				"DetailId: ", gp.DetailId, ",packName: ", gp.PackageName)
		} else {
			logs.Error("CreateYamlDetail, update cve_git_package_info failed, "+
				"packName: ", gp.PackageName, ",err: ", err)
			return gp.DetailId, "update", err
		}
		return gp.DetailId, "update", nil
	}
}

func CreateYamlSubPack(gb *GitSubPack) (SubId int64, typex string, err error) {
	o := orm.NewOrm()
	var localgb GitSubPack
	errx := o.Raw("select *"+
		" from cve_git_sub_pack where detail_id = ? and ids = ? and sub_pack_name = ?",
		gb.DetailId, gb.Ids, gb.SubPackName).QueryRow(&localgb)
	if errx != nil {
		var SubId int64
		if SubId, err = o.Insert(gb); err == nil {
			logs.Info("CreateYamlSubPack, insert cve_git_sub_pack success,"+
				" SubId: ", SubId, ",SubPackName: ", gb.SubPackName)
		} else {
			logs.Error("CreateYamlSubPack, insert cve_git_sub_pack failed, "+
				"SubPackName: ", gb.SubPackName, ",err: ", err)
			return 0, "insert", err
		}
		return SubId, "insert", nil
	}
	return localgb.SubId, "update", errx
}

func CreateYamlSubPackProvides(gs *GitSubPackProvides) (ProvideId int64, typex string, err error) {
	o := orm.NewOrm()
	var localgs GitSubPackProvides
	errx := o.Raw("select *"+
		" from cve_git_sub_pack_provides where sub_id = ? and ids = ? and provide_name = ?",
		gs.SubId, gs.Ids, gs.ProvideName).QueryRow(&localgs)
	if errx != nil {
		var ProvideId int64
		if ProvideId, err = o.Insert(gs); err == nil {
			logs.Info("CreateYamlSubPack, insert cve_git_sub_pack_provides success, "+
				"ProvideId: ", ProvideId, ", ProvideName: ", gs.ProvideName)
		} else {
			logs.Error("CreateYamlSubPack, insert cve_git_sub_pack_provides failed, "+
				"ProvideName: ", gs.ProvideName, ",err: ", err)
			return 0, "insert", err
		}
		return ProvideId, "insert", nil
	}
	return localgs.ProvideId, "update", errx
}

func CreateYamlSubPackRequiredb(gs *GitSubPackRequiredby) (Id int64, typex string, err error) {
	o := orm.NewOrm()
	var localgs GitSubPackRequiredby
	errx := o.Raw("select *"+
		" from cve_git_sub_pack_requiredby where provide_id = ? and requiredb = ?",
		gs.ProvideId, gs.Requiredby).QueryRow(&localgs)
	if errx != nil {
		var Id int64
		if Id, err = o.Insert(gs); err == nil {
			logs.Info("CreateYamlSubPackRequiredb, insert cve_git_sub_pack_requiredby success, "+
				"ID: ", Id, ", requiredb: ", gs.Requiredby)
		} else {
			logs.Error("CreateYamlSubPackRequiredb, insert cve_git_sub_pack_requiredby failed, "+
				"requiredb: ", gs.Requiredby, ", err: ", err)
			return 0, "insert", err
		}
		return Id, "insert", nil
	}
	return localgs.Id, "update", errx
}

func CreateYamlSubPackRequires(gs *GitSubPackRequire) (RequireId int64, typex string, err error) {
	o := orm.NewOrm()
	var localgs GitSubPackRequire
	errx := o.Raw("select *"+
		" from cve_git_sub_pack_require where sub_id = ? and ids = ? and require_name = ?",
		gs.SubId, gs.Ids, gs.RequireName).QueryRow(&localgs)
	if errx != nil {
		var RequireId int64
		if RequireId, err = o.Insert(gs); err == nil {
			logs.Info("CreateYamlSubPackRequires, insert cve_git_sub_pack_require success,"+
				" RequireId: ", RequireId, ",RequireName: ", gs.RequireName)
		} else {
			logs.Error("CreateYamlSubPackRequires, insert cve_git_sub_pack_require failed, "+
				"RequireName: ", gs.RequireName, ", err: ", err)
			return 0, "insert", err
		}
		return RequireId, "insert", nil
	}
	return localgs.RequireId, "update", errx
}

func QueryEulerRepoOrigin(ogk *OpenEulerRepoOrigin, field ...string) error {
	o := orm.NewOrm()
	err := o.Read(ogk, field...)
	return err
}

func QueryEulerRepoOriginByNmae(packageName string) (oer []OpenEulerRepoOrigin) {
	o := orm.NewOrm()
	num, geErr := o.Raw("select *"+
		" from cve_open_euler_repo_origin where package_name = ?", packageName).QueryRows(&oer)
	if num == 0 {
		logs.Error("QueryEulerRepoOriginByNmae, Get data does not exist, geErr: ", geErr)
	}
	return
}

// insert data
func InsertEulerRepoOrigin(ogk *OpenEulerRepoOrigin) (int64, error) {
	o := orm.NewOrm()
	id, err := o.Insert(ogk)
	return id, err
}

func UpdateEulerRepoOrigin(ogk *OpenEulerRepoOrigin, fields ...string) error {
	o := orm.NewOrm()
	_, err := o.Update(ogk, fields...)
	return err
}

func GetEulerYamlList(yamlId int64, count int) (oer []OpenEulerRepoOrigin) {
	o := orm.NewOrm()
	num, geErr := o.Raw("select *"+
		" from cve_open_euler_repo_origin where id > ? order by id asc limit ?", yamlId, count).QueryRows(&oer)
	if num == 0 {
		logs.Error("GetEulerYamlList, Get data does not exist, geErr: ", geErr)
	}
	return
}

func GetGitOpenEulerList(gitId int64, count int) (goe []GitOpenEuler) {
	o := orm.NewOrm()
	num, geErr := o.Raw("select *"+
		" from cve_git_open_euler where git_id > ? and package_id < ? and status = 1 order by git_id asc limit ?",
		gitId, 10000000, count).QueryRows(&goe)
	if num == 0 {
		logs.Error("GetGitOpenEulerList, Get data does not exist, geErr: ", geErr)
	}
	return
}

func DelOpenEulerRepoOriginByName(packageName string) {
	o := orm.NewOrm()
	_ = o.Raw("DELETE FROM cve_open_euler_repo_origin WHERE package_name = ?", packageName).QueryRow()
	return
}

func TruncateOpenEulerRepoOrigin() {
	o := orm.NewOrm()
	_ = o.Raw("TRUNCATE table cve_open_euler_repo_origin").QueryRow()
	return
}
